/*  
	------------------------------------------------------------------------
	 NQ Core Library
	
	 Homepage: http://www.awzhome.de/
	------------------------------------------------------------------------
	
	This Source Code Form is subject to the terms of the Mozilla Public
	License, v. 2.0. If a copy of the MPL was not distributed with this
	file, You can obtain one at http://mozilla.org/MPL/2.0/.
   
	The Original Code is code of NQ Core Library.

	The Initial Developer of the Original Code is Andreas Weizel.
	Portions created by the Initial Developer are
	Copyright (C) 2012 Andreas Weizel. All Rights Reserved.
	
	Contributor(s): (none)
	
	------------------------------------------------------------------------
*/

using System;
using System.Reflection;
using System.Linq;

namespace AWZhome.NQ.Core
{

	internal class NQComponentInfo : INQComponentInfo
	{
		private string _name;
		private string _displayName;
		private string _updaterURL;
		private string _copyright;
		private bool _isComponentPart = false;
		private string _nonTranslatedResKey = null;
		private string _nonTranslatedRes = null;
		private string _nonTranslatedPath = null;
		private string _translatedResKey = null;
		private string _translatedRes = null;
		private Version _version = null;
		private bool _noAutoLoad = false;
		private string _displayVersion = null;
		private NQHostMode _category = NQHostMode.General;
		private Assembly _mainAssembly;
		private Assembly[] _partAssemblies;
		private INQComponentRequirement[] _requires = null;
		private INQComponentRequirement[] _compatibility = null;

		internal NQComponentInfo(Assembly assembly)
		{
			NQComponentDefinitionAttribute cda = (NQComponentDefinitionAttribute) Attribute.GetCustomAttribute(assembly, typeof(NQComponentDefinitionAttribute));
			if (cda == null)
			{
				NQComponentPartAttribute cdp = (NQComponentPartAttribute) Attribute.GetCustomAttribute(assembly, typeof(NQComponentPartAttribute));
				if (cdp != null)
				{
					// Retrieve name of real component (this is only a part assembly of it)
					_name = cdp.Name;
					_isComponentPart = true;
				}
				else
				{
					// Somebody has tried to get info from an assembly which is not an NQ component
					throw new NQComponentDefinitionException(NQErrorReason.NonNQComponent, "Can't get component information from a non-NQ-component.");
				}
			}
			else
			{
				_mainAssembly = assembly;
				AssemblyCopyrightAttribute acopy = (AssemblyCopyrightAttribute) Attribute.GetCustomAttribute(assembly, typeof(AssemblyCopyrightAttribute));
				AssemblyDescriptionAttribute adesc = (AssemblyDescriptionAttribute) Attribute.GetCustomAttribute(assembly, typeof(AssemblyDescriptionAttribute));
				// Retrieve data from assembly
				_name = cda.Name;
				_displayName = cda.DisplayName;
				_updaterURL = cda.UpdaterURL;
				_category = cda.Category;
				_noAutoLoad = cda.NoAutoLoad;
				_copyright = acopy.Copyright;
				_version = assembly.GetName().Version;
				if (adesc != null)
				{
					if (!String.IsNullOrEmpty(adesc.Description))
					{
						_displayVersion = adesc.Description.Substring(1);
					}
					else
					{
						_displayName = _version.ToString();
					}
				}
				else
				{
					_displayVersion = _version.ToString();
				}

				// Check for resource definition
				NQResourceOwnerAttribute roa = (NQResourceOwnerAttribute) Attribute.GetCustomAttribute(assembly, typeof(NQResourceOwnerAttribute));
				if (roa != null)
				{
					_nonTranslatedResKey = roa.NonTranslatedKey;
					_nonTranslatedRes = roa.NonTranslatedName;
					_nonTranslatedPath = roa.NonTranslatedPath;
					_translatedResKey = roa.TranslatedKey;
					_translatedRes = roa.TranslatedName;
				}

				// Check for component requirements
				NQComponentRequirementAttribute[] rca = (NQComponentRequirementAttribute[]) Attribute.GetCustomAttributes(assembly, typeof(NQComponentRequirementAttribute));
				if (rca != null)
				{
					_requires = new INQComponentRequirement[rca.Length];
					for (int i = 0; i < rca.Length; i++)
					{
						_requires[i] = rca[i].ComponentRequirement;
					}
				}

				// Check for component compatibility
				NQComponentCompatibilityAttribute[] cca = (NQComponentCompatibilityAttribute[]) Attribute.GetCustomAttributes(assembly, typeof(NQComponentCompatibilityAttribute));
				if (cca != null)
				{
					_compatibility = new INQComponentRequirement[cca.Length];
					for (int i = 0; i < cca.Length; i++)
					{
						_compatibility[i] = cca[i].ComponentRequirement;
					}
				}
			}
		}

		public static bool IsComponent(Assembly assembly)
		{
			NQComponentDefinitionAttribute cda = (NQComponentDefinitionAttribute) Attribute.GetCustomAttribute(assembly, typeof(NQComponentDefinitionAttribute));
			if (cda == null)
			{
				// If there's no component definition, maybe it's a part of another component?
				NQComponentPartAttribute cdp = (NQComponentPartAttribute) Attribute.GetCustomAttribute(assembly, typeof(NQComponentPartAttribute));
				return (cdp != null);
			}
			else
			{
				return true;
			}
		}

		#region INQComponentInfo Members

		public string Name
		{
			get
			{
				return _name;
			}
		}

		public string DisplayName
		{
			get
			{
				return _displayName;
			}
		}

		public string UpdaterURL
		{
			get
			{
				return _updaterURL;
			}
		}

		public string Copyright
		{
			get
			{
				return _copyright;
			}
		}

		public bool IsComponentPart
		{
			get
			{
				return _isComponentPart;
			}
		}

		public string NonTranslatedResKey
		{
			get
			{
				return _nonTranslatedResKey;
			}
		}

		public string NonTranslatedRes
		{
			get
			{
				return _nonTranslatedRes;
			}
		}

		public string NonTranslatedPath
		{
			get
			{
				return _nonTranslatedPath;
			}
		}

		public string TranslatedResKey
		{
			get
			{
				return _translatedResKey;
			}
		}

		public string TranslatedRes
		{
			get
			{
				return _translatedRes;
			}
		}

		public INQComponentRequirement[] Requires
		{
			get
			{
				return _requires;
			}
		}

		public INQComponentRequirement[] Compatibility
		{
			get
			{
				return _compatibility;
			}
		}

		public Assembly MainAssembly
		{
			get
			{
				return _mainAssembly;
			}
		}

		public Assembly[] PartAssemblies
		{
			get
			{
				return _partAssemblies;
			}
			internal set
			{
				_partAssemblies = value;
			}
		}

		public Version Version
		{
			get
			{
				return _version;
			}
		}

		public string DisplayVersion
		{
			get
			{
				return _displayVersion;
			}
		}

		public bool NoAutoLoad
		{
			get
			{
				return _noAutoLoad;
			}
		}

		public NQHostMode Category
		{
			get
			{
				return _category;
			}
		}

		#endregion

	}

}